'************************************************************************************
' Copyright  2003-2005 Kathleen Dollard
'
' This software is provided 'as-is', without any express or implied warranty. In no 
' event will the author be held liable for any damages arising from the use of this
' software.
' 
' You may use this software for any purpose, including commercial applications, 
' and you may redistribute this software as part of application delivery: however, 
' this copyright notice may not be removed and you may not otherwise redistribute 
' this software directly other than providing a link to wwww.gendotnet.com. 
'
' You may alter this software to better server your needs (I'd like to hear about your 
' changes in order to make the software better). If you alter the softwre, you must  
' clearly mark it as altered and must not be misrepresented as the original software.
' nor wholly your original work.
'*************************************************************************************
'  Summary: The main utility class with miscellaneous tools

Option Strict On
Option Explicit On 

Imports System
Imports System.Diagnostics
Imports System.Collections.Generic

Namespace KADGen.Utility
   'Public Enum OutputType
   '   None
   '   VB
   '   CSharp
   '   XML
   '   StoredProc
   'End Enum

   'Public Enum GenType
   '   None
   '   Once
   '   UntilEdited
   '   Always
   '   Overwrite
   'End Enum



   Public Class Tools
      Public Const vbcrlf As String = Microsoft.VisualBasic.ControlChars.CrLf
      Public Const vbTab As String = Microsoft.VisualBasic.ControlChars.Tab

      Private Shared mSBForLog As New Text.StringBuilder
      Private Shared mStartTimeForLog As System.DateTime = System.DateTime.Now
      Private Shared mUtilityOverrides As UserUtility.UserUtilityOverrides

      Private Shared mVBKeywords As Dictionary(Of String, String)
      Private Shared mCSharpKeywords As Dictionary(Of String, String)

      Private Shared ReadOnly Property UtilityOverrides() As UserUtility.UserUtilityOverrides
         Get
            If mUtilityOverrides Is Nothing Then
               mUtilityOverrides = New UserUtility.UserUtilityOverrides
            End If
            Return mUtilityOverrides
         End Get
      End Property

      '! <Test Name=TempTest> ' Default level, No Parameters
      '!    <Group Name=Unit/>
      '!    <Result Type=String Value="Hello World"/>
      '! </Test>
      '!    
      Public Shared Function HelloWorld() As String
         Return "Hello World"
      End Function

      Public Function HelloWorld2() As String
         Return "Hello World 2"
      End Function

      '! <Test Name=TempTest> ' Default level
      '!    <Group Name=Unit/>
      '!    <Parameter Name=s Type=String Value=hello world />
      '!    <Result Type=String Value="HELLO WORLD"/>
      '! </Test>

      '! <DUT Name=TempTest2 Call=ToUpper("Hello World") Result="HELLO WORLD"/>

      '! <DUT Name=TempTest3>
      '!    <Prep Step="Dim s As String"/>
      '!    <Prep Step="s="Hello World""/>
      '!    <DUT Name=TempTest2 Call=ToUpper(s) Result="HELLO WORLD"/>
      '! </DUT>
      Public Function ToUpper(ByVal s As String) As String
         Return s.ToUpper
      End Function

      Public Shared Function SpaceAtCaps(ByVal s As String) As String
         ' The name is legacy, this also replaces underscores
         Dim chars() As Char = s.ToCharArray
         Dim sb As New Text.StringBuilder

         For i As Int32 = 0 To chars.GetUpperBound(0)
            If chars(i) = "_" Then
               sb.Append(" ")
            Else
               If (i > 0) AndAlso (IsSpaceChar(chars(i)) And Not IsSpaceChar(chars(i - 1))) Then
                  sb.Append(" ")
               End If
               sb.Append(chars(i))
            End If
         Next
         Return sb.ToString
      End Function
      Private Shared Function IsSpaceChar(ByVal c As Char) As Boolean
         Return System.Char.IsUpper(c) Or System.Char.IsNumber(c)
      End Function

      Public Shared Function CapAtSpaces(ByVal s As String) As String
         Dim chars() As Char = s.ToCharArray()
         If IsAllCaps(chars) Then
            s = s.ToLower
            chars = s.ToCharArray()
         End If
         Dim sb As New Text.StringBuilder
         For i As Int32 = 0 To chars.GetUpperBound(0)
            If i = 0 Then
               sb.Append(Char.ToUpper(chars(i)))
            ElseIf (chars(i - 1) = "_" Or chars(i - 1) = " ") Then
               sb.Append(Char.ToUpper(chars(i)))
            Else
               sb.Append(chars(i))
            End If
         Next
         Return sb.ToString
      End Function


      Public Shared Function IsAllCaps(ByVal s As String) As Boolean
         Return IsAllCaps(s.ToCharArray())
      End Function

      Public Shared Function IsAllCaps(ByVal charArray As Char()) As Boolean
         For i As Int32 = 0 To charArray.GetUpperBound(0)
            If Char.IsLetter(charArray(i)) Then
               ' If not a letter, consider OK and assume checked somewhere else for validity
               If Not Char.IsUpper(charArray(i)) Then
                  Return False
               End If
            End If
         Next
         Return True
      End Function

      Public Shared Function GetAttributeOrEmpty( _
                  ByVal node As Xml.XmlNode, _
                  ByVal ElementName As String, _
                  ByVal attributeName As String, _
                  ByVal nsmgr As Xml.XmlNamespaceManager) _
                  As String
         Dim elem As Xml.XmlNode
         If ElementName Is Nothing OrElse ElementName.Trim.Length = 0 Then
            Return GetAttributeOrEmpty(node, attributeName)
         Else
            elem = node.SelectSingleNode(ElementName, nsmgr)
            If elem Is Nothing Then
               Return ""
            Else
               Return GetAttributeOrEmpty(elem, attributeName)
            End If
         End If
      End Function

      Public Shared Function GetAttributeOrEmpty( _
                     ByVal node As Xml.XmlNode, _
                     ByVal attributeName As String) _
                     As String
         Dim ret As String = ""
         If Not node Is Nothing Then
            If Not node.Attributes Is Nothing Then
               Dim attr As Xml.XmlNode = node.Attributes.GetNamedItem(attributeName)
               If Not attr Is Nothing Then
                  ret = attr.Value
               End If
            End If
         End If
         Return ret
      End Function

      'Public Shared Function GetAttributeOrEmpty( _
      '            ByVal node As Xml.XmlNode, _
      '            ByVal attributeName As String, _
      '            ByVal nsMgr As Xml.XmlNamespaceManager) _
      '            As String
      '   Dim ret As String = ""
      '   If Not node Is Nothing Then
      '      If Not node.Attributes Is Nothing Then
      '         Dim attr As Xml.XmlNode = node.Attributes.GetNamedItem(attributeName)
      '         If Not attr Is Nothing Then
      '            ret = attr.Value
      '         End If
      '      End If
      '   End If
      '   Return ret
      'End Function

      Public Shared Function GetAttributeBooleanOrFalse( _
                 ByVal node As Xml.XmlNode, _
                 ByVal ElementName As String, _
                 ByVal attributeName As String, _
                 ByVal nsmgr As Xml.XmlNamespaceManager) _
                 As Boolean
         Dim elem As Xml.XmlNode
         If ElementName.Trim.Length = 0 Then
            Return GetAttributeBooleanOrFalse(node, attributeName)
         Else
            elem = node.SelectSingleNode(ElementName, nsmgr)
            If elem Is Nothing Then
               Return False
            Else
               Return GetAttributeBooleanOrFalse(elem, attributeName)
            End If
         End If
      End Function

      Public Shared Function GetAttributeBooleanOrFalse( _
                    ByVal node As Xml.XmlNode, _
                    ByVal attributeName As String) _
                    As Boolean
         Dim ret As String = ""
         If Not node Is Nothing Then
            If Not node.Attributes Is Nothing Then
               Dim attr As Xml.XmlNode = node.Attributes.GetNamedItem(attributeName)
               If Not attr Is Nothing Then
                  ret = attr.Value
               End If
            End If
         End If
         If Not ret Is Nothing AndAlso ret.Trim.ToLower = "true" Then
            Return True
         Else
            Return False
         End If
      End Function

      Public Shared Function GetAttributeIntegerOrZero( _
                   ByVal node As Xml.XmlNode, _
                   ByVal attributeName As String) _
                   As Int32
         Dim ret As String = ""
         If Not node Is Nothing Then
            If Not node.Attributes Is Nothing Then
               Dim attr As Xml.XmlNode = node.Attributes.GetNamedItem(attributeName)
               If Not attr Is Nothing Then
                  ret = attr.Value
               End If
            End If
         End If
         If ret Is Nothing OrElse ret.Trim.Length = 0 Then
            Return 0
         Else
            Return Convert.ToInt32(Microsoft.VisualBasic.Val(ret))
         End If
      End Function

      Public Shared Function GetAttributeFloatOrZero( _
                   ByVal node As Xml.XmlNode, _
                   ByVal attributeName As String) _
                   As Double
         Dim ret As String = ""
         If Not node Is Nothing Then
            If Not node.Attributes Is Nothing Then
               Dim attr As Xml.XmlNode = node.Attributes.GetNamedItem(attributeName)
               If Not attr Is Nothing Then
                  ret = attr.Value
               End If
            End If
         End If
         If ret Is Nothing OrElse ret.Trim.Length = 0 Then
            Return 0
         Else
            Return Microsoft.VisualBasic.Val(ret)
         End If
      End Function

      Public Shared Function GetAttributeDateOrMinDate( _
                   ByVal node As Xml.XmlNode, _
                   ByVal attributeName As String) _
                   As DateTime
         Dim ret As String = ""
         If Not node Is Nothing Then
            If Not node.Attributes Is Nothing Then
               Dim attr As Xml.XmlNode = node.Attributes.GetNamedItem(attributeName)
               If Not attr Is Nothing Then
                  ret = attr.Value
               End If
            End If
         End If
         If ret Is Nothing OrElse ret.Trim.Length = 0 Then
            Return System.DateTime.MinValue
         Else
            If Microsoft.VisualBasic.IsDate(ret) Then
               Return CDate(ret)
            End If
         End If
      End Function

      Public Shared Function GetAttributeEnumOrZero( _
              ByVal node As Xml.XmlNode, _
              ByVal attributeName As String, _
              ByVal enumType As System.Type) _
              As System.Object
         Dim s As String = Utility.Tools.GetAttributeOrEmpty(node, attributeName)
         If Not s.Trim.Length = 0 Then
            Return [Enum].Parse(enumType, s)
         End If
         Return Nothing
      End Function


      Public Shared Function HasAttribute( _
                  ByVal node As Xml.XmlNode, _
                  ByVal attributeName As String) _
                  As Boolean
         If Not node Is Nothing Then
            If Not node.Attributes Is Nothing Then
               Dim attr As Xml.XmlNode = node.Attributes.GetNamedItem(attributeName)
               Return Not attr Is Nothing
            End If
         End If
      End Function

      Public Shared Function FixPath( _
               ByVal sPath As String, _
               ByVal nodeFilePath As Xml.XmlNode) _
               As String
         Return FixPath(sPath, "", "", nodeFilePath)
      End Function

      Public Shared Function FixPath( _
                  ByVal sPath As String, _
                  ByVal basePath As String, _
                  ByVal docPath As String, _
                  ByVal nodeFilePath As Xml.XmlNode) _
                  As String
         ' Assume any square bracketed things should be in a path def in the XML
         Dim sStart As String
         Dim sEnd As String
         Dim sRet As String = sPath
         Dim sSearch As String = ""
         Dim sNew As String = ""
         Dim iStart As Int32
         Dim iEnd As Int32
         Dim node As Xml.XmlNode = Nothing
         Dim nsmgr As Xml.XmlNamespaceManager = _
                  xmlHelpers.BuildNameSpaceManager(nodeFilePath, "kg", False)
         Do While sRet.IndexOf("[") >= 0
            iStart = sRet.IndexOf("[")
            iEnd = sRet.IndexOf("]")
            sEnd = sRet.Substring(iEnd + 1)
            sSearch = sRet.Substring(iStart + 1, iEnd - iStart - 1)
            sStart = sRet.Substring(0, iStart)
            If sSearch.Trim.StartsWith("%") Then
               ' The following means embedded percents in configuration elements is not allowed
               sSearch = sSearch.Replace("%", "")
               Dim appSettings As Object = _
                     System.Configuration.ConfigurationManager.GetSection("userSettings/My.MySettings")
               If appSettings IsNot Nothing Then
                  With CType(appSettings, Configuration.ClientSettingsSection)
                     Dim setting As Configuration.SettingElement = .Settings.Get(sSearch)
                     If setting IsNot Nothing Then
                        Dim valueNode As Xml.XmlNode = setting.Value.ValueXml
                        If valueNode IsNot Nothing Then
                           sNew = valueNode.InnerText
                        End If
                     End If
                  End With
               End If
            Else
               If Not nodeFilePath Is Nothing Then
                  node = nodeFilePath.SelectSingleNode( _
                              "kg:FilePath[@Name='" & sSearch & "']", nsmgr)
               End If
               If node IsNot Nothing Then
                  ' Can't use a IO.Path.Combine here because of the variable segments
                  sNew = Tools.PathCombine( _
                              Utility.Tools.GetAttributeOrEmpty(node, "Path"), _
                              Utility.Tools.GetAttributeOrEmpty(node, "File"))
               Else
                  sNew = basePath
               End If
               'If sNew.StartsWith("/") Or sNew.StartsWith("\") Then
               '   sNew = sNew.Substring(1)
               'End If
               'If sEnd.StartsWith("/") Or sEnd.StartsWith("\") Then
               '   sEnd = sEnd.Substring(1)
               'End If
            End If
            sRet = Tools.PathCombine(Tools.PathCombine(sStart, sNew), sEnd)
            If Not docPath Is Nothing Then
               Tools.PathCombine(docPath, sRet)
            End If
         Loop
         ' Added 2005-09-12 KAD to allow environment variable support for abstract paths for Wind2
         sRet = System.Environment.ExpandEnvironmentVariables(sRet)


         'If Not nodeFilePath Is Nothing Then
         '   node = nodeFilePath.SelectSingleNode( _
         '               "kg:FilePath[@Name='" & s & "']", nsmgr)
         'End If
         'If Not node Is Nothing Then
         '   sNew = Utility.Tools.GetAttributeOrEmpty(node, "File")
         'End If
         'If Not sRet Is Nothing And Not sNew Is Nothing Then
         '   sRet = IO.Path.Combine(sRet, sNew)
         'End If
         Return sRet
      End Function

      'Public Shared Function FixFilter( _
      '            ByVal sPath As String, _
      '            ByVal nodeFilter As Xml.XmlNode) _
      '            As String
      '   ' Assume any square bracketed things should be in a path def in the XML
      '   Dim sEnd As String
      '   Dim sRet As String = ""
      '   Dim sSearch As String = ""
      '   Dim iEnd As Int32
      '   Dim node As Xml.XmlNode
      '   Dim parts() As String
      '   Dim nsmgr As Xml.XmlNamespaceManager = _
      '            xmlHelpers.BuildNameSpaceManager(nodeFilter, "kg", False)
      '   ' SUpport for multiple values added 8/13/04 KAD. NESTING CAN"T BE SUPPORTED BECAUSE OF AMBIGUOUS "["
      '   parts = sPath.Split("["c)
      '   For Each part As String In parts
      '      If part.Trim.Length = 0 Then
      '         ' skip it, nothing to do 
      '      Else
      '         node = Nothing
      '         sEnd = ""
      '         If part.IndexOf("]") >= 0 Then
      '            iEnd = part.IndexOf("]")
      '            If iEnd > 0 Then
      '               sEnd = part.Substring(iEnd + 1)
      '               sSearch = part.Substring(0, iEnd)
      '               If Not nodeFilter Is Nothing Then
      '                  node = nodeFilter.SelectSingleNode( _
      '                              "kg:Filter[@Name=" & """" & sSearch & """" & "]", nsmgr)
      '               End If

      '            End If
      '         End If
      '         If Not node Is Nothing Then
      '            sRet &= Utility.Tools.GetAttributeOrEmpty(node, "Filter") & sEnd
      '         Else
      '            sRet &= part
      '         End If
      '      End If
      '   Next
      '   Return sRet
      'End Function

      'Public Shared Function FixPath( _
      '               ByVal sPath As String, _
      '               ByVal basePath As String, _
      '               ByVal docPath As String, _
      '               ByVal nodeFilePath As Xml.XmlNode) _
      '               As String
      '   ' Assume any square bracketed things should be in a path def in the XML
      '   Dim s As String = ""
      '   Dim sRet As String = sPath
      '   Dim sFragment As String = sPath
      '   Dim sNew As String = ""
      '   Dim iStart As Int32
      '   Dim iEnd As Int32
      '   Dim node As Xml.XmlNode
      '   Dim nsmgr As Xml.XmlNamespaceManager = _
      '            Tools.BuildNameSpaceManager(nodeFilePath, "kg", False)
      '   Do While sRet.IndexOf("[") >= 0
      '      iStart = sRet.IndexOf("[")
      '      iEnd = sRet.IndexOf("]")
      '      sFragment = sRet.Substring(iEnd + 1)
      '      s = sRet.Substring(iStart + 1, iEnd - iStart - 1)
      '      sRet = sRet.Substring(0, iStart)
      '      If Not nodeFilePath Is Nothing Then
      '         node = nodeFilePath.SelectSingleNode( _
      '                     "kg:FilePath[@Name='" & s & "']", nsmgr)
      '      End If
      '      If Not node Is Nothing Then
      '         sNew = System.IO.Path.Combine( _
      '                     Utility.Tools.GetAttributeOrEmpty(node, "Path"), _
      '                     Utility.Tools.GetAttributeOrEmpty(node, "File"))
      '      Else
      '         sNew = basePath
      '      End If
      '      If Not sNew Is Nothing Then
      '         If sNew.StartsWith("/") Or sNew.StartsWith("\") Then
      '            sNew = sNew.Substring(1)
      '         End If
      '         If sFragment.StartsWith("/") Or sFragment.StartsWith("\") Then
      '            sFragment = sFragment.Substring(1)
      '         End If
      '         sRet = IO.Path.Combine(IO.Path.Combine(sRet, sNew), sFragment)
      '         If Not docPath Is Nothing Then
      '            IO.Path.Combine(docPath, sRet)
      '         End If
      '      End If
      '   Loop
      '   'If Not nodeFilePath Is Nothing Then
      '   '   node = nodeFilePath.SelectSingleNode( _
      '   '               "kg:FilePath[@Name='" & s & "']", nsmgr)
      '   'End If
      '   'If Not node Is Nothing Then
      '   '   sNew = Utility.Tools.GetAttributeOrEmpty(node, "File")
      '   'End If
      '   'If Not sRet Is Nothing And Not sNew Is Nothing Then
      '   '   sRet = IO.Path.Combine(sRet, sNew)
      '   'End If
      '   Return sRet
      'End Function



      Public Shared Function GetAnnotOrEmpty( _
                     ByVal node As Xml.XmlNode, _
                     ByVal attributeName As String) _
                     As String
         Dim nodeTmp As Xml.XmlNode
         nodeTmp = node.SelectSingleNode("annotation[@" & attributeName & "]")
         If Not nodeTmp Is Nothing Then
            Return Tools.GetAttributeOrEmpty(nodeTmp, attributeName)
         Else
            Return ""
         End If
      End Function

      Public Shared Function GetAnnotOrEmpty( _
                     ByVal node As Xml.XmlNode, _
                     ByVal attributeName As String, _
                     ByVal nsmgr As Xml.XmlNamespaceManager) _
                     As String
         Dim nodeTmp As Xml.XmlNode
         nodeTmp = node.SelectSingleNode("xs:annotation[@" & attributeName & "]", nsmgr)
         If Not nodeTmp Is Nothing Then
            Return Tools.GetAttributeOrEmpty(nodeTmp, attributeName)
         Else
            Return ""
         End If
      End Function


      Public Shared Function GetMethodInfo( _
                     ByVal node As Xml.XmlNode, _
                     ByVal callingType As System.Type, _
                     ByVal nsmgr As Xml.XmlNamespaceManager, _
                     ByVal nodeFilePath As Xml.XmlNode) _
                     As Reflection.MethodInfo
         Return GetMethodInfo(node, callingType, nsmgr, "", "", "", nodeFilePath)
      End Function

      Public Shared Function GetMethodInfo( _
                      ByVal node As Xml.XmlNode, _
                      ByVal callingType As System.Type, _
                      ByVal nsmgr As Xml.XmlNamespaceManager, _
                      ByVal basePath As String, _
                      ByVal docPath As String, _
                      ByVal nodeFilePath As Xml.XmlNode) _
                      As Reflection.MethodInfo
         Return GetMethodInfo(node, callingType, nsmgr, "", basePath, docPath, nodeFilePath)
      End Function

      Public Shared Function GetMethodInfo( _
                     ByVal node As Xml.XmlNode, _
                     ByVal callingType As System.Type, _
                     ByVal nsmgr As Xml.XmlNamespaceManager, _
                     ByVal elem As String, _
                     ByVal basePath As String, _
                     ByVal docPath As String, _
                     ByVal nodeFilePath As Xml.XmlNode) _
                     As Reflection.MethodInfo
         Dim name As String
         Dim type As System.Type
         Dim methodInfo As Reflection.MethodInfo
         If node Is Nothing Then
         Else
            type = GetSpecifiedType(node, callingType, nsmgr, elem, basePath, docPath, nodeFilePath)
            name = Tools.GetAttributeOrEmpty(node, elem, "MethodName", nsmgr)
            If name.Trim.Length = 0 Then
               name = StripNamespacePrefix(Tools.GetAttributeOrEmpty(node, elem, "name", nsmgr))
            End If
            methodInfo = type.GetMethod(name, Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Static Or Reflection.BindingFlags.IgnoreCase Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic)
            Return methodInfo
         End If
         Return Nothing
      End Function


      Public Shared Function GetMethodInfo( _
                     ByVal callingType As System.Type, _
                     ByVal assemblyFileName As String, _
                     ByVal assemblyName As String, _
                     ByVal typeName As String, _
                     ByVal methodName As String) _
                     As Reflection.MethodInfo
         Dim type As System.Type
         Dim methodInfo As Reflection.MethodInfo
         type = GetSpecifiedType(callingType, assemblyFileName, assemblyName, typeName)
         methodInfo = type.GetMethod(methodName, Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Static Or Reflection.BindingFlags.IgnoreCase Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic)
         Return methodInfo
      End Function

      Public Shared Function GetSpecifiedType( _
                     ByVal node As Xml.XmlNode, _
                     ByVal callingType As System.Type, _
                     ByVal nsmgr As Xml.XmlNamespaceManager, _
                     ByVal elem As String, _
                     ByVal basePath As String, _
                     ByVal docPath As String, _
                     ByVal nodeFilePath As Xml.XmlNode) _
                     As System.Type
         Dim assemblyFilename As String
         Dim assemblyName As String
         Dim typeName As String
         Dim type As System.Type
         assemblyFilename = Tools.FixPath(Tools.GetAttributeOrEmpty(node, elem, "AssemblyFileName", nsmgr), basePath, docPath, nodeFilePath)
         assemblyName = Tools.GetAttributeOrEmpty(node, elem, "AssemblyName", nsmgr)
         typeName = Tools.GetAttributeOrEmpty(node, elem, "TypeName", nsmgr)
         type = GetSpecifiedType(callingType, assemblyFilename, assemblyName, typeName)
         Return type
      End Function

      Public Shared Function GetSpecifiedType( _
                     ByVal callingType As System.Type, _
                     ByVal assemblyFileName As String, _
                     ByVal assemblyName As String, _
                     ByVal typeName As String) _
                     As System.Type
         Dim asm As System.Reflection.Assembly
         Dim type As System.Type
         If Not assemblyFileName Is Nothing AndAlso assemblyFileName.Trim.Length > 0 Then
            ' KAD: 20070706: Changed from LoadFile to LoadFrom
            asm = Reflection.Assembly.LoadFrom(assemblyFileName)
         ElseIf Not assemblyName Is Nothing AndAlso assemblyName.Trim.Length > 0 Then
            asm = Reflection.Assembly.Load(assemblyName)
         Else
            asm = callingType.Assembly
         End If

         If Not asm Is Nothing And (Not typeName Is Nothing AndAlso typeName.Trim.Length > 0) Then
            Return GetSpecifiedType(asm, typeName)
         Else
            type = callingType
         End If
         Return type
      End Function

      Public Shared Function GetSpecifiedType( _
               ByVal asm As Reflection.Assembly, _
               ByVal name As String) _
               As System.Type
         Dim type As System.Type = Nothing
         ' Kind of ugly but it works
         For Each testType As System.Type In asm.GetTypes
            If testType.Name.ToLower = name.ToLower Then
               type = testType
            End If
         Next
         Return type
      End Function


      Public Shared Function StripNamespacePrefix( _
                     ByVal name As String) _
                     As String
         If name.IndexOf(":") >= 0 Then
            Return name.Substring(name.IndexOf(":") + 1)
         Else
            Return name
         End If
      End Function

      Public Shared Function StringArrayFromNodeList( _
                     ByVal nodeList As Xml.XmlNodeList) _
                     As String()
         Return StringArrayFromNodeList(nodeList, "value")
      End Function
      Public Shared Function StringArrayFromNodeList( _
                     ByVal nodeList As Xml.XmlNodeList, _
                     ByVal attrName As String) _
                     As String()
         Dim ret() As String
         ReDim ret(nodeList.Count - 1)
         For i As Int32 = 0 To ret.GetUpperBound(0)
            ret(i) = GetAttributeOrEmpty(nodeList(i), attrName)
         Next
         Return ret
      End Function

      Public Shared Function StripPrefix(ByVal s As String) As String
         If s.IndexOf(":") >= 0 Then
            Return s.Substring(s.IndexOf(":") + 1)
         Else
            Return s
         End If
      End Function

      Public Shared Function GetSQLTypeFromXSDType(ByVal XSDTypeName As String) As String
         Dim localType As String = xmlHelpers.GetLocalPart(XSDTypeName)

         Select Case localType.ToLower
            Case "string"
               Return "varchar"
            Case "integer", "int"
               Return "int"
            Case "long"
               Return "bigint"
            Case "short"
               Return "smallint"
            Case "int"
               Return "int"
            Case "boolean"
               Return "bit"
            Case "decimal", "number", "double"
               Return "real"
            Case "single"
               Return "float"
            Case "unsignedbyte", "unsignedint", "byte"
               Return localType.ToLower
            Case Else
               ' KAD: 20060806: Changed so we could tell whether real SQL type
               'Return localType.ToLower
               Return String.Empty
         End Select
      End Function

      Public Shared Function GetNetTypeFromXSDType(ByVal XSDTypeName As String) As String
         Dim localType As String = xmlHelpers.GetLocalPart(XSDTypeName)

         Select Case localType.ToLower
            Case "number", "decimal"
               Return "System.Decimal"
            Case "float"
               Return "System.Single"
            Case "double"
               Return "System.Double"
            Case "byte"
               Return "System.SByte"
            Case "short"
               Return "System.Int16"
            Case "integer", "int"
               Return "System.Int32"
            Case "long"
               Return "System.Int64"
            Case "unsignedbyte"
               Return "System.Byte"
            Case "unsignedshort"
               Return "System.UInt16"
            Case "unsignedint", "positiveinteger", "nonnegativeinteger"
               Return "System.UInt32"
            Case "unsignedlong"
               Return "System.UInt64"
            Case "boolean"
               Return "System.Boolean"
            Case "string"
               Return "System.String"
            Case Else
               ' KAD: 20060806: Changed so we could tell whether real SQL type
               'Return localType.ToLower
               Return String.Empty
         End Select
      End Function

      Public Shared Function GetSQLTypeFromSQLType( _
                        ByVal SQLTypeName As String) _
                        As String
         ' This is kind of ugly, and currently we don't store the 
         ' original type, trusting this synonum and case insensitity
         Select Case SQLTypeName.ToLower
            Case "numeric"
               SQLTypeName = "decimal"
         End Select
         ' This is to fix the case for C#
         ' Swallow the exception here becasue we swallowed it before
         Try
            SQLTypeName = [Enum].Parse(GetType(Data.SqlDbType), SQLTypeName, True).ToString
         Catch ex As Exception
            Diagnostics.Debug.WriteLine("Illegal type name")
         End Try
         Return SQLTypeName
      End Function

      Public Shared Function GetNETTypeFromSQLType( _
                        ByVal SQLTypeName As String) _
                        As String
         ' Bytes go to square brackets becuase that's how IL does it, and 
         ' to maximize fidelity.
         ' I'm using parens for Byte because C# is more likely to be using hte new alias.
         ' and becuase that's what I've done historically.
         Select Case SQLTypeName.ToLower
            Case "int"
               Return "System.Int32"
            Case "smallint"
               Return "System.Int16"
            Case "bigint"
               Return "System.Int64"
            Case "decimal"
               Return "System.Decimal"
            Case "base64binary"
               Return "System.Byte()"
            Case "boolean"
               Return "System.Boolean"
            Case "datetime"
               Return "System.DateTime"
            Case "float"
               Return "System.Double"
            Case "real"
               Return "System.Single"
            Case "unsignedbyte"
               Return "System.Byte"
            Case "byte"
               Return "System.SByte"
            Case "unsignedint"
               Return "System.UInt32"
            Case "char", "nchar", "varchar", "nvarchar", "ntext", "text"
               Return "System.String"
            Case "datetime", "smalldatetime"
               Return "System.DateTime"
            Case "money", "smallmoney", "numeric"
               Return "System.Decimal"
            Case "bit"
               Return "System.Boolean"
            Case "tinyint"
               Return "System.Byte"
            Case "timestamp"
               Return "System.Byte()"
            Case "uniqueidentifier"
               Return "System.Guid"
            Case "image", "binary", "varbinary"
               Return "System.Byte()" ' This is an issue as it is VB or C# specific
            Case Else
               Debug.WriteLine("type not found - {0}", SQLTypeName)
         End Select
         Return String.Empty
      End Function

      Public Shared Function GetVBNETTypeFromNetType(ByVal netType As String) As String
         Select Case netType.ToLower
            Case "system.byte[]"
               Return "System.Byte()"
            Case Else
               Return netType
         End Select
      End Function

      Public Shared Function GetVBTypeAliasFromNetType(ByVal netType As String) As String
         Select Case netType.ToLower
            Case "system.int32"
               Return "Integer"
            Case "system.int16"
               Return "Short"
            Case "system.int64"
               Return "Long"
            Case "system.boolean"
               Return "Boolean"
            Case "system.double"
               Return "Double"
            Case "system.single"
               Return "Single"
            Case "system.decimal"
               Return "Decimal"
            Case "system.byte"
               Return "Byte"
            Case "system.string"
               Return "String"
            Case "system.datetime"
               Return "Date"
            Case "system.byte[]"
               Return "System.Byte()" ' So, even if the NETTypes are C#, the VBAlias is correct
            Case Else
               Return netType
         End Select
      End Function

      Public Shared Function GetCSharpTypeAliasFromNetType(ByVal netType As String) As String
         Select Case netType.ToLower
            Case "system.int32"
               Return "int"
            Case "system.int16"
               Return "short"
            Case "system.int64"
               Return "long"
            Case "system.boolean"
               Return "bool"
            Case "system.double"
               Return "double"
            Case "system.single"
               Return "float"
            Case "system.decimal"
               Return "decimal"
            Case "system.byte"
               Return "byte"
            Case "system.byte()"
               Return "byte[]"
            Case "system.string"
               Return "string"
            Case Else
               Return netType
         End Select
      End Function

      Public Shared Function GetPrefix( _
               ByVal name As String, _
               ByVal prefixList As String, _
               ByVal removeAllPrefixes As Boolean) _
               As String
         Dim prefixes() As String = prefixList.Split(","c)

         For Each prefix As String In prefixes
            If prefix.Trim.Length > 0 Then
               prefix = prefix.Trim
               If name.StartsWith(prefix) Then
                  Return prefix
               End If
            End If
         Next

         If removeAllPrefixes Then
            For i As Int32 = 0 To name.Length - 1
               If Char.IsUpper(Convert.ToChar(name.Substring(i, 1))) Then
                  Return name.Substring(0, i)
               End If
            Next
         End If

         Return ""
      End Function

      Public Shared Function FixName( _
                  ByVal name As String) As String
         ' This is used by stylesheets. Don't delete just becuase its not otherwise in use
         ' These are the defaults that seem most logical to the templates
         Return FixName(name, False, "", False, False, "LeadingUnderscore", "VB", "ReplaceWithUnderscore")
      End Function

      Public Shared Function FixName( _
                  ByVal name As String, _
                  ByVal removePrefix As Boolean) As String
         Return FixName(name, removePrefix, "", False, False, "", "", "")
      End Function

      Public Shared Function FixName( _
                  ByVal name As String, _
                  ByVal removePrefix As Boolean, _
                  ByVal keywordTreatment As String) As String
         Return FixName(name, False, "", False, False, keywordTreatment, "", "")
      End Function

      Public Shared Function FixName( _
                   ByVal name As String, _
                   ByVal removeAllPrefixes As Boolean, _
                   ByVal prefixes As String, _
                   ByVal friendlyCaps As Boolean, _
                   ByVal removeUnderscores As Boolean, _
                   ByVal keywordTreatment As String, _
                   ByVal targetLanguage As String, _
                   ByVal blankTreatment As String) As String
         Dim ret As String = name.Trim
         Dim keywords As String
         Dim prefix As String

         prefix = GetPrefix(ret, prefixes, removeAllPrefixes)
         ret = ret.Substring(prefix.Length)

         If friendlyCaps Then
            ret = CapAtSpaces(ret)
         End If

         Dim replaceText As String
         If blankTreatment = "Remove" Then
            replaceText = ""
         Else
            replaceText = "_"
         End If
         ret = ReplaceFriendly(ret, " ", replaceText, friendlyCaps)

         ' Remove illegal characters. Currently this follows same pattern as spaces
         ' BTW, if you space and put the same character in this that you are using to replace, you get an infinite loop. Fair warning.
         ' I am currently preserving square brackets. This may not work with C#
         ' This may be too aggressive
         Dim illegal() As String = {"/", "\", "<", ">", ";", ",", ".", "?", "'", "{", "}", "+", "-", "=", "|", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")"}
         For Each ill As String In illegal
            If ret.IndexOf(ill) > 0 Then
               ret = ReplaceFriendly(ret, ill, replaceText, friendlyCaps)
            End If
         Next

         If removeUnderscores Then
            ret = ret.Replace("_", "")
         End If

         If keywordTreatment <> "None" Then
            ret = FixKeyword(ret, keywordTreatment)
         End If
         Return ret
      End Function

      Public Shared Function FixKeyword( _
               ByVal s As String, _
               ByVal keywordTreatment As String) _
               As String

         Dim ret As String = s
         ' replace c# keywords(C# is case sensitive)
         If mCSharpKeywords Is Nothing Then
            mCSharpKeywords = New Dictionary(Of String, String)
            mCSharpKeywords.Add("abstract", Nothing)
            mCSharpKeywords.Add("as", Nothing) ' Could potentially be a plural problem
            mCSharpKeywords.Add("base", Nothing)
            mCSharpKeywords.Add("bool", Nothing)
            mCSharpKeywords.Add("break", Nothing)
            mCSharpKeywords.Add("byte", Nothing)
            mCSharpKeywords.Add("case", Nothing)
            mCSharpKeywords.Add("catch", Nothing)
            mCSharpKeywords.Add("char", Nothing)
            mCSharpKeywords.Add("checked", Nothing)
            mCSharpKeywords.Add("class", Nothing)
            mCSharpKeywords.Add("const", Nothing)
            mCSharpKeywords.Add("continue", Nothing)
            mCSharpKeywords.Add("decimal", Nothing)
            mCSharpKeywords.Add("default", Nothing)
            mCSharpKeywords.Add("delegate", Nothing)
            mCSharpKeywords.Add("do", Nothing)
            mCSharpKeywords.Add("double", Nothing)
            mCSharpKeywords.Add("else", Nothing)
            mCSharpKeywords.Add("enum", Nothing)
            mCSharpKeywords.Add("event", Nothing)
            mCSharpKeywords.Add("explicit", Nothing)
            mCSharpKeywords.Add("extern", Nothing)
            mCSharpKeywords.Add("false", Nothing)
            mCSharpKeywords.Add("finally", Nothing)
            mCSharpKeywords.Add("fixed", Nothing)
            mCSharpKeywords.Add("float", Nothing)
            mCSharpKeywords.Add("for", Nothing)
            mCSharpKeywords.Add("foreach", Nothing)
            mCSharpKeywords.Add("goto", Nothing)
            mCSharpKeywords.Add("if", Nothing)
            mCSharpKeywords.Add("implicit", Nothing)
            mCSharpKeywords.Add("in", Nothing)
            mCSharpKeywords.Add("int", Nothing)
            mCSharpKeywords.Add("interface", Nothing)
            mCSharpKeywords.Add("internal", Nothing)
            mCSharpKeywords.Add("is", Nothing) ' Could potentially be a plural problem
            mCSharpKeywords.Add("lock", Nothing)
            mCSharpKeywords.Add("long", Nothing)
            mCSharpKeywords.Add("namespace", Nothing)
            mCSharpKeywords.Add("new", Nothing)
            mCSharpKeywords.Add("null", Nothing)
            mCSharpKeywords.Add("object", Nothing)
            mCSharpKeywords.Add("operator", Nothing)
            mCSharpKeywords.Add("out", Nothing)
            mCSharpKeywords.Add("override", Nothing)
            mCSharpKeywords.Add("param", Nothing)
            mCSharpKeywords.Add("private", Nothing)
            mCSharpKeywords.Add("protected", Nothing)
            mCSharpKeywords.Add("public", Nothing)
            mCSharpKeywords.Add("readonly", Nothing)
            mCSharpKeywords.Add("ref", Nothing)
            mCSharpKeywords.Add("return", Nothing)
            mCSharpKeywords.Add("sbyte", Nothing)
            mCSharpKeywords.Add("sealed", Nothing)
            mCSharpKeywords.Add("short", Nothing)
            mCSharpKeywords.Add("sizeof", Nothing)
            mCSharpKeywords.Add("stackalloc", Nothing)
            mCSharpKeywords.Add("static", Nothing)
            mCSharpKeywords.Add("string", Nothing)
            mCSharpKeywords.Add("struct", Nothing)
            mCSharpKeywords.Add("switch", Nothing)
            mCSharpKeywords.Add("this", Nothing) ' Could potentially be a plural problem
            mCSharpKeywords.Add("throw", Nothing)
            mCSharpKeywords.Add("true", Nothing)
            mCSharpKeywords.Add("try", Nothing)
            mCSharpKeywords.Add("typeof", Nothing)
            mCSharpKeywords.Add("uint", Nothing)
            mCSharpKeywords.Add("ulong", Nothing)
            mCSharpKeywords.Add("unchecked", Nothing)
            mCSharpKeywords.Add("unsafe", Nothing)
            mCSharpKeywords.Add("ushort", Nothing)
            mCSharpKeywords.Add("using", Nothing)
            mCSharpKeywords.Add("virtual", Nothing)
            mCSharpKeywords.Add("void", Nothing)
            mCSharpKeywords.Add("volatile", Nothing)
            mCSharpKeywords.Add("while", Nothing)
         End If
         If mCSharpKeywords.ContainsKey(ret) And keywordTreatment <> "VB" Then
            ret = MungeKeyword(ret, keywordTreatment)
         End If

         ' replace vb keywords (vb is not case sensitive)
         If mVBKeywords Is Nothing Then
            mVBKeywords = New Dictionary(Of String, String)
            mVBKeywords.Add("addhandler", Nothing)
            mVBKeywords.Add("addressof", Nothing)
            mVBKeywords.Add("andalso", Nothing)
            mVBKeywords.Add("alias", Nothing) ' Could potentially be a plural problem
            mVBKeywords.Add("and", Nothing)
            mVBKeywords.Add("ansi", Nothing)
            mVBKeywords.Add("as", Nothing)  ' Could potentially be a plural problem
            mVBKeywords.Add("assembly", Nothing)
            mVBKeywords.Add("auto", Nothing)
            mVBKeywords.Add("boolean", Nothing)
            mVBKeywords.Add("byref", Nothing)
            mVBKeywords.Add("byte", Nothing)
            mVBKeywords.Add("byval", Nothing)
            mVBKeywords.Add("call", Nothing)
            mVBKeywords.Add("case", Nothing)
            mVBKeywords.Add("catch", Nothing)
            mVBKeywords.Add("cbool", Nothing)
            mVBKeywords.Add("cbyte", Nothing)
            mVBKeywords.Add("cchar", Nothing)
            mVBKeywords.Add("cdate", Nothing)
            mVBKeywords.Add("cdec", Nothing)
            mVBKeywords.Add("cdbl", Nothing)
            mVBKeywords.Add("char", Nothing)
            mVBKeywords.Add("cint", Nothing)
            mVBKeywords.Add("class", Nothing)
            mVBKeywords.Add("clng", Nothing)
            mVBKeywords.Add("cobj", Nothing)
            mVBKeywords.Add("const", Nothing)
            mVBKeywords.Add("cshort", Nothing)
            mVBKeywords.Add("csng", Nothing)
            mVBKeywords.Add("cstr", Nothing)
            mVBKeywords.Add("ctype", Nothing)
            mVBKeywords.Add("date", Nothing)
            mVBKeywords.Add("decimal", Nothing)
            mVBKeywords.Add("declare", Nothing)
            mVBKeywords.Add("default", Nothing)
            mVBKeywords.Add("delegate", Nothing)
            mVBKeywords.Add("dim", Nothing)
            mVBKeywords.Add("directcast", Nothing)
            mVBKeywords.Add("do", Nothing)
            mVBKeywords.Add("double", Nothing)
            mVBKeywords.Add("each", Nothing)
            mVBKeywords.Add("else", Nothing)
            mVBKeywords.Add("elseif", Nothing)
            mVBKeywords.Add("end", Nothing)
            mVBKeywords.Add("enum", Nothing)
            mVBKeywords.Add("erase", Nothing)
            mVBKeywords.Add("error", Nothing)
            mVBKeywords.Add("event", Nothing)
            mVBKeywords.Add("exit", Nothing)
            mVBKeywords.Add("false", Nothing)
            mVBKeywords.Add("finally", Nothing)
            mVBKeywords.Add("for", Nothing)
            mVBKeywords.Add("friend", Nothing)
            mVBKeywords.Add("function", Nothing)
            mVBKeywords.Add("get", Nothing)
            mVBKeywords.Add("gettype", Nothing)
            mVBKeywords.Add("gosub", Nothing)
            mVBKeywords.Add("goto", Nothing)
            mVBKeywords.Add("handles", Nothing)  ' ** Probable plural problem
            mVBKeywords.Add("if", Nothing)
            mVBKeywords.Add("implements", Nothing) ' ** Probable plural problem
            mVBKeywords.Add("imports", Nothing) ' ** Probable plural problem
            mVBKeywords.Add("in", Nothing)
            mVBKeywords.Add("inherits", Nothing) ' ** Probable plural problem
            mVBKeywords.Add("integer", Nothing)
            mVBKeywords.Add("interface", Nothing)
            mVBKeywords.Add("is", Nothing) ' Could potentially be a plural problem
            mVBKeywords.Add("let", Nothing)
            mVBKeywords.Add("lib", Nothing)
            mVBKeywords.Add("like", Nothing)
            mVBKeywords.Add("long", Nothing)
            mVBKeywords.Add("loop", Nothing)
            mVBKeywords.Add("me", Nothing)
            mVBKeywords.Add("mod", Nothing)
            mVBKeywords.Add("module", Nothing)
            mVBKeywords.Add("mustinherit", Nothing)
            mVBKeywords.Add("mustoverride", Nothing)
            mVBKeywords.Add("mybase", Nothing)
            mVBKeywords.Add("myclass", Nothing)
            mVBKeywords.Add("namespace", Nothing)
            mVBKeywords.Add("new", Nothing)
            mVBKeywords.Add("next", Nothing)
            mVBKeywords.Add("not", Nothing)
            mVBKeywords.Add("nothing", Nothing)
            mVBKeywords.Add("notinheritable", Nothing)
            mVBKeywords.Add("notoverridable", Nothing)
            mVBKeywords.Add("object", Nothing)
            mVBKeywords.Add("on", Nothing)
            mVBKeywords.Add("option", Nothing)
            mVBKeywords.Add("optional", Nothing)
            mVBKeywords.Add("or", Nothing)
            mVBKeywords.Add("orelse", Nothing)
            mVBKeywords.Add("overloads", Nothing) ' ** Probable plural problem
            mVBKeywords.Add("overridable", Nothing)
            mVBKeywords.Add("overrides", Nothing)   ' ** Probable plural problem
            mVBKeywords.Add("paramarray", Nothing)
            mVBKeywords.Add("preserve", Nothing)
            mVBKeywords.Add("private", Nothing)
            mVBKeywords.Add("property", Nothing)
            mVBKeywords.Add("protected", Nothing)
            mVBKeywords.Add("public", Nothing)
            mVBKeywords.Add("raiseevent", Nothing)
            mVBKeywords.Add("readonly", Nothing)
            mVBKeywords.Add("redim", Nothing)
            mVBKeywords.Add("rem", Nothing)
            mVBKeywords.Add("removehandler", Nothing)
            mVBKeywords.Add("resume", Nothing)
            mVBKeywords.Add("return", Nothing)
            mVBKeywords.Add("select", Nothing)
            mVBKeywords.Add("set", Nothing)
            mVBKeywords.Add("shadows", Nothing)  ' ** Probable plural problem
            mVBKeywords.Add("shared", Nothing)
            mVBKeywords.Add("short", Nothing)
            mVBKeywords.Add("single", Nothing)
            mVBKeywords.Add("static", Nothing)
            mVBKeywords.Add("step", Nothing)
            mVBKeywords.Add("stop", Nothing)
            mVBKeywords.Add("string", Nothing)
            mVBKeywords.Add("structure", Nothing)
            mVBKeywords.Add("sub", Nothing)
            mVBKeywords.Add("synclock", Nothing)
            mVBKeywords.Add("then", Nothing)
            mVBKeywords.Add("throw", Nothing)
            mVBKeywords.Add("to", Nothing)
            mVBKeywords.Add("true", Nothing)
            mVBKeywords.Add("try", Nothing)
            mVBKeywords.Add("typeof", Nothing)
            mVBKeywords.Add("unicode", Nothing)
            mVBKeywords.Add("until", Nothing)
            mVBKeywords.Add("variant", Nothing)
            mVBKeywords.Add("when", Nothing)
            mVBKeywords.Add("while", Nothing)
            mVBKeywords.Add("with", Nothing)
            mVBKeywords.Add("withevents", Nothing)  '  ' Could potentially be a plural problem
            mVBKeywords.Add("writeonly", Nothing)
            mVBKeywords.Add("xor", Nothing)
         End If
         If mVBKeywords.ContainsKey(ret.ToLower()) And keywordTreatment <> "CSharp" Then
            ret = MungeKeyword(ret, keywordTreatment)
         End If
         Return ret
      End Function

      Private Shared Function MungeKeyword(ByVal s As String, ByVal keywordTreatment As String) As String
         If keywordTreatment = "TrailingUnderscore" Then
            Return s & "_"
         ElseIf keywordTreatment = "LeadingUnderscore" Then
            Return "_" & s
         ElseIf keywordTreatment = "VB" Then
            Return "[" & s & "]"
         ElseIf keywordTreatment = "CSharp" Then
            Return "@" & s
         Else
            Return s
         End If
      End Function

      Private Shared Function ReplaceFriendly( _
               ByVal inString As String, _
               ByVal replaceString As String, _
               ByVal replaceWith As String, _
               ByVal friendlyCaps As Boolean) _
               As String
         Dim ret As String = inString
         Dim pos As Int32
         pos = ret.IndexOf(replaceString)

         While pos >= 0
            Dim firstPart As String = ret.Substring(0, pos)
            Dim secondPart As String = ret.Substring(pos + 1)
            If friendlyCaps Then
               secondPart = secondPart.Substring(0, 1).ToUpper() & _
                            secondPart.Substring(1)
            End If
            ret = firstPart & replaceWith & secondPart
            pos = ret.IndexOf(replaceString)
         End While
         Return ret
      End Function

      Public Shared Function GetSingular(ByVal name As String) As String
         Return UtilityOverrides.GetSingular(name)
      End Function


      Public Shared Function GetPlural(ByVal name As String) As String
         Return UtilityOverrides.GetPlural(name)
      End Function

      Public Shared Function IsPlural(ByVal s As String) As Boolean
         If s.EndsWith("s") Then
            ' it might be plural. Here is a simple test we can expand as needed
            s = s.Substring(0, s.Length - 1)
            If s.EndsWith("s") Then
               Return False
            ElseIf s.EndsWith("u") Then
               Return False
            Else
               Return True
            End If
         End If
      End Function

      Public Shared Sub MakePathIfNeeded(ByVal fileName As String)
         Dim path As String = IO.Path.GetDirectoryName(fileName)
         If Not path.Length = 0 Then
            If path.StartsWith("http://") Then
               Throw New System.ApplicationException("Creating subdirectories in virtual directories is not supported. Please create these directories by hand and rerun code gen")
            Else
               If Not IO.Directory.Exists(path) Then
                  IO.Directory.CreateDirectory(path)
               End If
            End If
         End If
      End Sub

      Public Shared Function GetEmbeddedXsd( _
               ByVal type As System.Type, _
               ByVal name As String) _
               As Xml.Schema.XmlSchema
         Dim xsdStream As IO.Stream = Nothing
         Try
            xsdStream = GetStreamFromStringResource(type, name)
            Return Xml.Schema.XmlSchema.Read(xsdStream, Nothing)
         Finally
            If xsdStream IsNot Nothing Then
               xsdStream.Close()
            End If
         End Try
      End Function

      Public Shared Function GetEmbeddedXslt( _
               ByVal type As System.Type, _
               ByVal name As String) _
               As Xml.Xsl.XslCompiledTransform
         Dim xsltStream As IO.Stream = Nothing
         Dim xmlReader As Xml.XmlTextReader = Nothing
         Dim xslt As New Xml.Xsl.XslCompiledTransform
         Try
            xsltStream = GetStreamFromStringResource(type, name)
            xmlReader = New Xml.XmlTextReader(xsltStream)
            xslt.Load(xmlReader, Nothing, Nothing)
            Return xslt
         Finally
            If xmlReader IsNot Nothing Then
               xmlReader.Close()
            End If
            If xsltStream IsNot Nothing Then
               xsltStream.Close()
            End If
         End Try
      End Function

      Public Shared Function GetStreamFromStringResource( _
               ByVal type As System.Type, _
               ByVal name As String) _
               As IO.Stream
         Dim asm As Reflection.Assembly
         Dim stream As IO.Stream
         ' Whether the namespace is present appears to depend on the way 
         ' the namespace is defined (VB project namespaces). So, I am 
         ' trying with and without namespace from type
         asm = type.Assembly
         stream = asm.GetManifestResourceStream(type, name)
         If stream Is Nothing Then
            stream = asm.GetManifestResourceStream(name)
         End If
         Return stream
      End Function

      Public Shared Function SubstringBefore( _
                  ByVal searchIn As String, _
                  ByVal searchFor As String) _
                  As String
         Return SubstringBefore(searchIn, searchFor, True)
      End Function

      Public Shared Function SubstringAfter( _
                  ByVal searchIn As String, _
                  ByVal searchFor As String) _
                  As String
         Return SubstringAfter(searchIn, searchFor, True)
      End Function

      Public Shared Function SubstringAfterLast( _
                  ByVal searchIn As String, _
                  ByVal searchFor As String) _
                  As String
         Return SubstringAfterLast(searchIn, searchFor, True)
      End Function

      Public Shared Function SubstringBefore( _
                  ByVal searchIn As String, _
                  ByVal searchFor As String, _
                  ByVal IsCaseSensitive As Boolean) _
                  As String
         If Not IsCaseSensitive Then
            searchIn = searchIn.ToLower
            searchFor = searchFor.ToLower
         End If
         Dim ipos As Int32 = searchIn.IndexOf(searchFor)
         Return searchIn.Substring(0, ipos)
      End Function

      Public Shared Function SubstringAfter( _
                  ByVal searchIn As String, _
                  ByVal searchFor As String, _
                  ByVal IsCaseSensitive As Boolean) _
                  As String
         If Not IsCaseSensitive Then
            searchIn = searchIn.ToLower
            searchFor = searchFor.ToLower
         End If
         Dim ipos As Int32 = searchIn.IndexOf(searchFor)
         Return searchIn.Substring(ipos + searchFor.Length)
      End Function

      Public Shared Function SubstringAfterLast( _
                  ByVal searchIn As String, _
                  ByVal searchFor As String, _
                  ByVal IsCaseSensitive As Boolean) _
                  As String
         If Not IsCaseSensitive Then
            searchIn = searchIn.ToLower
            searchFor = searchFor.ToLower
         End If
         Dim ipos As Int32 = searchIn.LastIndexOf(searchFor)
         Return searchIn.Substring(ipos + searchFor.Length)
      End Function

      Public Shared Function SubstringBefore( _
                  ByVal searchIn As String, _
                  ByVal searchFor() As String) As String
         Return SubstringBefore(searchIn, searchFor, True)
      End Function

      Public Shared Function SubstringAfter( _
                  ByVal searchIn As String, _
                  ByVal searchFor() As String) As String
         Return SubstringAfter(searchIn, searchFor, True)
      End Function

      Public Shared Function SubstringAfterLast( _
                  ByVal searchIn As String, _
                  ByVal searchFor() As String) As String
         Return SubstringAfterLast(searchIn, searchFor, True)
      End Function

      Public Shared Function SubstringContains( _
                  ByVal searchIn As String, _
                  ByVal searchFor() As String) As Boolean
         Return SubstringContains(searchIn, searchFor, True)
      End Function

      Public Shared Function SubstringContainsWhich( _
                  ByVal searchIn As String, _
                  ByVal searchFor() As String) As String
         Return SubstringContainsWhich(searchIn, searchFor, True)
      End Function

      Public Shared Function SubstringBefore( _
                  ByVal searchIn As String, _
                  ByVal searchFor() As String, _
                  ByVal IsCaseSensitive As Boolean) As String
         Dim find As String
         If Not IsCaseSensitive Then
            searchIn = searchIn.ToLower
         End If
         For i As Int32 = 0 To searchFor.GetLength(0)
            If IsCaseSensitive Then
               find = searchFor(i)
            Else
               find = searchFor(i).ToLower
            End If
            If searchIn.IndexOf(find) > 0 Then
               Dim ipos As Int32 = searchIn.IndexOf(find)
               Return searchIn.Substring(0, ipos + 1)
            End If
         Next
         Return Nothing
      End Function

      Public Shared Function SubstringAfter( _
                  ByVal searchIn As String, _
                  ByVal searchFor() As String, _
                  ByVal IsCaseSensitive As Boolean) As String
         Dim find As String
         If Not IsCaseSensitive Then
            searchIn = searchIn.ToLower
         End If
         For i As Int32 = 0 To searchFor.GetLength(0)
            If IsCaseSensitive Then
               find = searchFor(i)
            Else
               find = searchFor(i).ToLower
            End If
            If searchIn.IndexOf(find) > 0 Then
               Dim ipos As Int32 = searchIn.IndexOf(find)
               Return searchIn.Substring(ipos + searchFor.Length)
            End If
         Next
         Return Nothing
      End Function

      Public Shared Function SubstringAfterLast( _
                  ByVal searchIn As String, _
                  ByVal searchFor() As String, _
                  ByVal IsCaseSensitive As Boolean) As String
         Dim find As String
         If Not IsCaseSensitive Then
            searchIn = searchIn.ToLower
         End If
         For i As Int32 = 0 To searchFor.GetLength(0)
            If IsCaseSensitive Then
               find = searchFor(i)
            Else
               find = searchFor(i).ToLower
            End If
            If searchIn.IndexOf(find) > 0 Then
               Dim ipos As Int32 = searchIn.LastIndexOf(find)
               Return searchIn.Substring(ipos + searchFor.Length)
            End If
         Next
         Return Nothing
      End Function

      Public Shared Function SubstringContains( _
                  ByVal searchIn As String, _
                  ByVal searchFor() As String, _
                  ByVal IsCaseSensitive As Boolean) As Boolean
         Dim find As String
         If Not IsCaseSensitive Then
            searchIn = searchIn.ToLower
         End If
         For i As Int32 = 0 To searchFor.GetLength(0)
            If IsCaseSensitive Then
               find = searchFor(i)
            Else
               find = searchFor(i).ToLower
            End If
            If searchIn.IndexOf(find) > 0 Then
               Return True
            End If
         Next
      End Function

      Public Shared Function SubstringContainsWhich( _
                  ByVal searchIn As String, _
                  ByVal searchFor() As String, _
                  ByVal IsCaseSensitive As Boolean) As String
         Dim find As String
         Dim index As Int32
         Dim maxIndex As Int32
         Dim pos As Int32 = -1
         If Not IsCaseSensitive Then
            searchIn = searchIn.ToLower
         End If
         For i As Int32 = 0 To searchFor.GetLength(0)
            If IsCaseSensitive Then
               find = searchFor(i)
            Else
               find = searchFor(i).ToLower
            End If
            index = searchIn.IndexOf(find)
            If index > 0 Then
               If index < maxIndex Then
                  pos = i
               End If
            End If
         Next
         Return searchFor(pos)
      End Function

      Public Shared Function GetMatchingParenPosition( _
                  ByVal s As String) _
                  As Int32
         Return GetMatchingPunctuation(s, "("c, ")"c)
      End Function

      Public Shared Function GetMatchingPunctuation( _
                  ByVal s As String, _
                  ByVal punc1 As Char, _
                  ByVal punc2 As Char) _
                  As Int32
         Dim iDepth As Int32
         Dim chars() As Char = s.ToCharArray
         If punc1 = punc2 Then
            Throw New System.ApplicationException("The GetMatchingPunctuation method doesn't work with matching open and close characters")
         End If
         If s.IndexOf(punc1) >= 0 Then
            For i As Int32 = 0 To s.Length - 1
               If chars(i) = punc1 Then
                  iDepth += 1
               ElseIf chars(i) = punc2 Then
                  iDepth -= 1
               End If
               If iDepth = 0 Then
                  Return i
               End If
            Next
            Throw New System.ApplicationException("Improperly nested parentheses")
         Else
            Return -1
         End If

      End Function

      Public Shared Function CharArrayToString(ByVal chars() As Char, _
                    ByVal startpos As Int32) _
                    As String
         Return CharArrayToString(chars, startpos, chars.GetLength(0))
      End Function

      Public Shared Function CharArrayToString(ByVal chars() As Char) _
                 As String
         Return CharArrayToString(chars, 0, chars.GetLength(0))
      End Function

      Public Shared Function CharArrayToString(ByVal chars() _
                     As Char, _
                     ByVal startpos As Int32, _
                     ByVal length As Int32) As String
         Dim sb As New Text.StringBuilder
         For i As Int32 = startpos To length - 1
            sb.Append(chars(i))
         Next
         Return sb.ToString
      End Function

      Public Shared Function Test(ByVal node As Xml.XmlNode) As String
         Return "George"
      End Function

      Public Shared Function Test2(ByVal node As Xml.XPath.XPathNavigator) As String
         Return "Ron"
      End Function

      Public Shared Function Test3(ByVal node As Xml.XPath.XPathNodeIterator) As String
         Return "Ginny"
      End Function

      'Public Shared Function TranslateSQLExpression( _
      '               ByVal constraint As String, _
      '               ByVal currentObject As String, _
      '               ByVal currentProperty As String) _
      '               As Xml.XmlNode
      '   Dim xmlDoc As Xml.XmlDocument
      '   Dim nsmgr As Xml.XmlNamespaceManager
      '   Dim oTranslate As New TranslateSQL
      '   xmlDoc = KADGen.LibraryInterop.Singletons.XMLDoc
      '   nsmgr = KADGen.LibraryInterop.Singletons.NsMgr
      '   Dim node As Xml.XmlNode = xmlDoc.CreateElement("CheckConstraint")
      '   node.Attributes.Append(xmlHelpers.NewAttribute(xmlDoc, "Fred", "True"))
      '   node.Attributes.Append(xmlHelpers.NewAttribute(xmlDoc, "OriginalClause", constraint))
      '   node.Attributes.Append(xmlHelpers.NewAttribute(xmlDoc, "VBClause", oTranslate.TranslateSQLToVB(constraint, currentObject, currentProperty, xmlDoc, nsmgr, True)))
      '   node.Attributes.Append(xmlHelpers.NewAttribute(xmlDoc, "CSharpClause", oTranslate.TranslateSQLToVB(constraint, currentObject, currentProperty, xmlDoc, nsmgr, True)))
      '   node.Attributes.Append(xmlHelpers.NewAttribute(xmlDoc, "EnglishClause", oTranslate.TranslateSQLToEnglish(constraint, currentObject, currentProperty, xmlDoc, nsmgr)))
      '   Return node

      'End Function

      'Public Shared Sub LogEntry(ByVal sMessage As String)
      '   'mSBForLog.Append(DateTime.Now.Ticks.ToString("N") & "-" & sMessage & vbcrlf)
      '   Dim dt As DateTime = DateTime.Now
      '   Dim tickcount As Int64
      '   Static ticks As Int64
      '   If ticks = 0 Then
      '      ticks = DateTime.Now.Ticks
      '   End If
      '   tickcount = (DateTime.Now.Ticks - ticks)
      '   If tickcount > 160000 Then
      '      mSBForLog.Append("*** ")
      '   Else
      '      mSBForLog.Append("    ")
      '   End If
      '   mSBForLog.Append(dt.ToString("T") & ":" & dt.Millisecond.ToString("000") & _
      '                     "(" & (tickcount \ 10000).ToString("000,000") & _
      '                     ") -" & sMessage & vbcrlf)
      '   ticks = DateTime.Now.Ticks
      '   If DateTime.Now.Subtract(mStartTimeForLog).Seconds > 10 Then
      '      mStartTimeForLog = DateTime.Now
      '   End If
      '   If False Then
      '      mSBForLog = New Text.StringBuilder
      '      Throw New System.Exception
      '   End If
      'End Sub

      Public Shared Sub WriteLogAndClear(ByVal sFileName As String)
         If mSBForLog.Length > 0 Then
            Dim writer As New IO.StreamWriter(sFileName)
            writer.Write(mSBForLog.ToString)
            writer.Flush()
            writer.Close()
            mSBForLog = New Text.StringBuilder
         End If
      End Sub

      Public Shared Function StringOrEmpty(ByVal obj As Object) As String
         If obj Is Nothing Then
            Return ""
         ElseIf obj.ToString.Trim.ToLower = "true" Then
            Return "true"
         ElseIf obj.ToString.Trim.ToLower = "false" Then
            Return "false"
         Else
            Return obj.ToString
         End If
      End Function

      Public Shared Function BuildFromPattern( _
                     ByVal pattern As String, _
                     ByVal hashTable As Collections.Hashtable) _
                     As String
         Dim sRet As String = pattern
         Dim iStart As Int32
         Dim iEnd As Int32
         Dim sEnd As String
         Dim sSearch As String
         Dim sStart As String
         Dim sNew As String

         Do While sRet.IndexOf("[") >= 0
            iStart = sRet.IndexOf("[")
            iEnd = sRet.IndexOf("]")
            sEnd = sRet.Substring(iEnd + 1)
            sSearch = sRet.Substring(iStart + 1, iEnd - iStart - 1)
            sStart = sRet.Substring(0, iStart)
            sNew = CStr(hashTable(sSearch))
            sRet = sStart & sNew & sEnd
         Loop
         Return sRet
      End Function

      Public Shared Function PathCombine( _
                     ByVal file1 As String, _
                     ByVal file2 As String) _
                     As String
         ' This is used instead of IO.Path.Combine when the file names contain illegal characters
         ' such as before the segment replacement in CodeGeneration harness
         If file1.EndsWith("\") Or file1.EndsWith("/") Then
            file1 = file1.Substring(0, file1.Length - 1)
         End If
         If file2.StartsWith("\") Or file2.StartsWith("/") Then
            file2 = file2.Substring(1)
         End If
         If file1.Trim.Length = 0 Then
            Return file2.Trim
         ElseIf file2.Trim.Length = 0 Then
            Return file1.Trim
         Else
            Return file1.Trim & "\" & file2.Trim
         End If
      End Function

      Public Shared Function StartsWithNumeric(ByVal val As String) As Boolean
         Dim c As Char
         c = System.Convert.ToChar(val.Substring(0, 1))
         Return Char.IsNumber(c)
      End Function

      Public Shared Function XMLFriendlyName(ByVal val As String) As String
         Dim ret As String = val
         If Not val Is Nothing AndAlso val.Trim.Length > 0 Then
            If StartsWithNumeric(ret) Then
               ret = "_" & ret
            End If
            ret = ret.Replace(".", "_")
            ret = ret.Replace(" ", "_")
         End If
         Return ret
      End Function

      Public Shared Function RemoveSpaces(ByVal s As String) As String
         Return s.Replace(" ", "")
      End Function

   End Class
End Namespace